package com.vinhvt.effiport.application.sample.mapper;

import com.vinhvt.effiport.algorithm.genetic.bio.Individual;
import com.vinhvt.effiport.algorithm.genetic.bio.WeightGene;
import com.vinhvt.effiport.algorithm.genetic.mapper.GeneMap;
import com.vinhvt.effiport.algorithm.genetic.mapper.IMapper;
import com.vinhvt.effiport.application.sample.Function;
import com.vinhvt.effiport.application.sample.Variable;
import com.vinhvt.effiport.util.Helper;



public class FunctionMapper implements IMapper {
	private Function function = null;
	private Individual indiv = null;
	private FunctionGeneMap map = null;
	
	public Function getFunction() {
		return this.function;
	}
	
	public Individual getIndividual() {
		return this.indiv;
	}
	
	public FunctionMapper(GeneMap map) {
		this.setMap((FunctionGeneMap)map);
	}
	
	private void setMap(GeneMap map) {		
		this.map = (FunctionGeneMap)map;
	}

	private Variable getVariable(int position) {
		String name = map.getName(position);
		Variable var = new Variable();
		var.setName(name);			
		
		return var;
	}
	
	@Override
	public void cipherADN() {		
		double x1 = function.getVariable(0).getValue();
		double x2 = function.getVariable(1).getValue();
		if (x1 + x2 == 0)
		{
			x1 = 0.5;
			x2 = 0.5;
		}
		double x11 = x1 / (x1 + x2);
		double x22 = x2 / (x1 + x2);
		
		WeightGene gene1 = new WeightGene(x11);
		indiv.getChrWeight().addGene(gene1);
		
		WeightGene gene2 = new WeightGene(x22);
		indiv.getChrWeight().addGene(gene2);
		

	}

	@Override
	public void decipherADN() {
		// TODO Auto-generated method stub
//		int times = 2;
//		for(int i = 0; i < times; i++) {
//			double value = 0;
//			try{
//			value = Helper.round(indiv.getChrWeight().getGene(i).getValue().doubleValue());
//			}
//			catch (Exception e) {
//				e.printStackTrace();
//				
//			}
//			Variable var =  this.getVariable(i);
//			this.function.addVariable(var, value);
//			
//		}
		double x1 = Helper.round(indiv.getChrWeight().getGene(0).getValue().doubleValue()); 						
		double x2 = Helper.round(indiv.getChrWeight().getGene(1).getValue().doubleValue());	
		if (x1 + x2 == 0) {
			x1 = 0.5;
			x2 = 0.5;
		}
		double x11 = x1 / (x1 + x2);
		double x22 = x2 / (x1 + x2);
		Variable var1 =  this.getVariable(0);
		this.function.addVariable(var1, x11);
		
		Variable var2 =  this.getVariable(1);
		this.function.addVariable(var2, x22);
		
	}


	@Override
	public void map2Coding(Object obj1) {
		this.function = (Function) obj1;
		this.indiv = new Individual();
		
		double fitness = function.calcValue();
		
		//punishment
		

		fitness = Math.max(0, 80000 - fitness);
		indiv.setFitness(fitness);
		
		cipherADN();

	}

	@Override
	public void map2Solution(Object obj2) {
		this.indiv = (Individual) obj2;
		this.function = new Function();
		decipherADN();
		cipherADN();
		double fitness = function.calcValue();
		
		//punishment
		
		
		fitness = Math.max(0, 80000 - fitness);
		this.indiv.setFitness(fitness);

	}

}
